/**
 * options: 字典数据
 * strict: 启用value严格相等
 */
export class DictClass {
  strict = true;
  cache = {};
  constructor(options, strict) {
    Object.defineProperty(this, 'options', {
      get() {
        return Array.isArray(options) ? options : [];
      }
    });
    if (typeof strict === 'boolean') {
      this.strict = strict;
    }
  }
  get keys() {
    // return this.options.map(v => v.label);
    let obj = {};
    this.options.forEach(item => {
      obj[item.label] = item;
    });
    return obj;
  }
  get values() {
    // return this.options.map(v => v.value);
    let obj = {};
    this.options.forEach(item => {
      obj[item.value] = item;
    });
    return obj;
  }
  get getThis() {
    return this;
  }
  // 根据value获取对应的label
  getLabel(val, defaultVal) {
    if (!this.cache.hasOwnProperty(val)) {
      this._cacheItem(val);
    }
    if (this.cache[val]) {
      return this.cache[val].label;
    }
    return defaultVal;
  }
  // 根据value获取所在item
  getItem(val) {
    if (!this.cache.hasOwnProperty(val)) {
      this._cacheItem(val);
    }
    return this.cache[val];
  }
  // 依据 strict 判断是严格相等还是弱相等
  _isEqual(val, value) {
    if (this.strict) {
      return val === value;
    }
    return val == value;
  }
  // 依据 value 找对应的 item 进行缓存
  _cacheItem(val) {
    let result = null;
    for (let item of this.options) {
      if (this._isEqual(val, item.value)) {
        result = item;
        break;
      }
    }
    if (result) {
      this.cache[val] = Object.freeze(result);
    }
  }
}

export class Constant {
  _values = [];
  _labels = [];
  _status = [];
  constructor(options) {
    this.options = options;
    for (const key in options) {
      const { label, value, status } = options[key];
      this._values[key] = value;
      this._labels[key] = label;
      this._status[key] = status;
      this[key] = value;
    }
    Object.freeze(this);
  }
  map() {
    return Object.values(this.options);
  }
  getLabel(key) {
    return this._labels[key];
  }
  getValue(key) {
    return this._values[key];
  }
  getStatus(key) {
    return this._status[key];
  }
}
